package com.demo.login;

import com.demo.common.model.SystemRes;
import com.demo.common.model.SystemRole;
import com.demo.common.model.SystemUser;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.ByteSource;

import java.util.List;

public class ShiroDbRealm extends AuthorizingRealm {

    /**
     * 认证回调函数,登录时调用,返回的 info 与录入的 token比对
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {

        UsernamePasswordToken authcToken = (UsernamePasswordToken) token;
        String accountName = authcToken.getUsername();

        SystemUser user = SystemUser.dao.findByEmail(accountName);
        if (null == user)
            throw new AuthenticationException("用户名或者密码错误");
        if (user.isLocked())
            throw new LockedAccountException("该用户已被锁定");

        return new SimpleAuthenticationInfo(user.getEmail(), user.getPwd(),
                ByteSource.Util.bytes(user.getEmail() + user.getSalt2()), getName());
    }

    /**
     * 授权查询回调函数,进行鉴权但缓存中无用户的授权信息时调用.
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //User user = (User) principals.fromRealm(getName()).iterator().next();
        String username = (String) principals.fromRealm(getName()).iterator().next();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if (null == username) {
            return info;
        }
        SystemUser user = SystemUser.dao.findByEmail(username);
        if (null == user) {
            return info;
        }
        List<SystemRole> roles = SystemRole.dao.getRoles(user.getId());
        if (CollectionUtils.isNotEmpty(roles)) {
            for (SystemRole role : roles) {
                // 保存角色的名称及角色的权限
                info.addRole(role.getName());
                info.addStringPermissions(SystemRes.dao.getResUrls(SystemRes.dao.getReses(role)));
            }
        }
        return info;
    }

    /**
     * 更新用户授权信息缓存.
     */
    public void clearCachedAuthorizationInfo(String principal) {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        clearCachedAuthorizationInfo(principals);
    }

    /**
     * 清除所有用户授权信息缓存.
     */
    public void clearAllCachedAuthorizationInfo() {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null) {
            for (Object key : cache.keys()) {
                cache.remove(key);
            }
        }
    }
}
